/*************************************************************************** 
 * (c) 2006 Dmitry Osinovsky, osdmsoftware@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 ***************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Resources;
using OsdmSoftware.CommonLibrary;

namespace OsdmSoftware.PocketPicture
{
    public class Action
    {
        // Run-time properties
        PocketPictureForm form;
        //ToolBarButton button;
        //MenuItem menuItem;
        //Menu childMenu;
        ToolPanelElement element;

        ToolMenu parentMenu;
        int imageIndex = -1;
        int ownImageIndex;
        bool horizontalDropDown = false;
        bool showImagesInDropDown = true;
        bool displayCheckBoxIfNoImage = true;
        bool closeDropDownOnClick = true;
        bool createImageWithTextIfNoImage = true;

        public bool HorizontalDropDown { get { return horizontalDropDown; } set { horizontalDropDown = value; } }
        public bool ShowImagesInDropDown { get { return showImagesInDropDown; } set { showImagesInDropDown = value; } }
        public bool DisplayCheckBoxIfNoImage { get { return displayCheckBoxIfNoImage; } set { displayCheckBoxIfNoImage = value; } }
        public PocketPictureForm Form { get { return form; } set { form = value; } }
        public ToolPanelElement Element { get { return element; } }
        public bool CloseDropDownOnClick { get { return closeDropDownOnClick; } set { closeDropDownOnClick = value; } }
        public bool CreateImageWithTextIfNoImage { get { return createImageWithTextIfNoImage; } set { createImageWithTextIfNoImage = value; } }

        //public ToolBarButton Button { get { return button; } set { button = value; } }
        //public MenuItem MenuItem { get { return menuItem; } set { menuItem = value; } }
        //public Menu ChildMenu { get { return childMenu; } }

        public ToolMenu ParentMenu { get { return parentMenu; } }
        public int ImageIndex { get { return imageIndex; } set { imageIndex = value; } }
        public int OwnImageIndex { get { return ownImageIndex; } }

        // Serializable properties
        string name;
        string imageName;
        string parentName = "MainToolBar";
        bool createChildMenu;
        string hint;

        public string Name { get { return name; } set { name = value; } }
        public string ImageName { get { return imageName; } set { imageName = value; } }
        public string ParentName { get { return parentName; } set { parentName = value; } }
        public string Hint { get { return hint; } set { hint = value; } }
        public bool CreateChildMenu { get { return createChildMenu; } set { createChildMenu = value; } }

        public virtual void DrawImage(Graphics gr)
        {
            if (createImageWithTextIfNoImage)
                gr.DrawString(name, new Font("Arial", 7, FontStyle.Regular), new SolidBrush(Color.Black), 0, 0);
        }

        public virtual void CreateUI(PocketPictureForm form)
        {
            this.form = form;

            if (imageIndex == -1 && imageName != null && imageName != "")
            {
                object obj = null;
#if !SmallIcons
                if (Form.ImageList.ImageSize.Width == 16)
#endif
                {
                    try
                    {
                        obj = OsdmSoftware.PocketPicture.Properties.Resources.ResourceManager.GetObject(ImageName + "16");
                    }
                    catch (MissingManifestResourceException)
                    {
                        obj = null;
                    }
                }

                if (obj == null)
                {
                    try
                    {
                        obj = OsdmSoftware.PocketPicture.Properties.Resources.ResourceManager.GetObject(ImageName);
                    }
                    catch (MissingManifestResourceException)
                    {
                        obj = null;
                    }
                }

                if (obj != null)
                {
                    //Bitmap bmp1 = BitmapCloner.CloneBitmap((Bitmap) (obj));
                    Bitmap bmp1 = (Bitmap) (obj);

                    /*Bitmap bmp2 = new Bitmap(bmp1.Width, bmp1.Height, PixelFormat.Format32bppRgb);
                    Graphics gr = Graphics.FromImage(bmp2);
                    gr.FillRectangle(new SolidBrush(SystemColors.Control), 0, 0, bmp1.Width, bmp1.Height);
                    ImageAttributes attrs = new ImageAttributes();
                    attrs.SetColorKey(Color.White, Color.White);
                    gr.DrawImage(bmp1, 
                        new Rectangle(0, 0, bmp1.Width, bmp1.Height), 
                        0, 0, bmp1.Width, bmp1.Height,
                        GraphicsUnit.Pixel, attrs);
                    gr.Dispose();*/
                    imageIndex = form.ImageList.Images.Count;
                    form.ImageList.Images.Add(bmp1);
                }
            }

            if (imageIndex == -1)
            {
                Bitmap bmp = new Bitmap(Form.ImageList.ImageSize.Width, Form.ImageList.ImageSize.Height/*, PixelFormat.Format32bppRgb*/);
                Graphics gr = Graphics.FromImage(bmp);
                gr.FillRectangle(new SolidBrush(Color.White), 0, 0, Form.ImageList.ImageSize.Width, Form.ImageList.ImageSize.Height);
                DrawImage(gr);
                gr.Dispose();

                imageIndex = form.ImageList.Images.Count;
                form.ImageList.Images.Add(bmp);
            }

            List<ToolPanelElement> l;

            if (parentName == "MainToolBar")
            {
                l = form.MainToolBar.ChildElements;
                parentMenu = null;
            }
            else
            {
                if (!form.Menus.TryGetValue(parentName, out parentMenu))
                    Trace.Assert(false, "Could not find parent menu " + parentName + " for action" + name);
                l = parentMenu.Elements;
            }

            ToolPanelElement btn = new ToolPanelElement();

            if (imageIndex != -1)
            {
                btn.ImageIndex = imageIndex;
            }

            btn.Text = name;
            btn.Tag = this;
            if (horizontalDropDown)
            {
                btn.DropDownOrientation = Orientation.Horizontal;
                btn.DropDownShowText = ShowTextEnum.ShowTextIfNoImage;
                btn.DropDownTextPosition = TextPositionEnum.TextBelowImage;
            }
            else
            {
                btn.DropDownOrientation = Orientation.Vertical;
                btn.DropDownShowText = ShowTextEnum.AlwaysShowText;
                btn.DropDownTextPosition = TextPositionEnum.TextAfterImage;
            }

            if (createChildMenu)
            {
                /*btn.Style = ToolBarButtonStyle.DropDownButton;
                ContextMenu cm = new ContextMenu();
                btn.DropDownMenu = cm;
                childMenu = cm;*/
            }

            l.Add(btn);
            this.element = btn;

            /*if (parentMenu != null)
            {
                if (!Form.DefaultMenuItems.ContainsKey(parentMenu))
                {
                    Form.SetDefaultAction(parentMenu, this);
                }
            }

            if (createChildMenu)
            {
                Form.Menus.Add(name, this);
            }*/

            ownImageIndex = imageIndex;
            closeDropDownOnClick = !createChildMenu;
        }

        public virtual void DoAction()
        {
            if (parentMenu != null)
            {
                //Form.SetDefaultAction(parentMenu, this);
            }
        }

        public void SetPushed(bool on)
        {
            element.IsPushed = on;
            element.Refresh();
            /*if (parentMenu != null && parentMenu is ToolCollection)
            {
                if (parentMenu.parentMenu == null)
                    parentMenu.SetPushed(on);
            }*/
        }

        public virtual void UpdatePicture(Action childAction)
        {
        }
    }

    public class SubMenuAction: Action
    {
        ToolMenu[] menus;

        public ToolMenu[] Menus { get { return menus; } set { menus = value; } }

        PaintTool defaultPaintTool;

        public PaintTool DefaultPaintTool { get { return defaultPaintTool; } set { defaultPaintTool = value; } }

        public SubMenuAction(string name, string imageName, ToolMenu[] menus, string hint, PaintTool defaultPaintTool)
        {
            this.Name = name;
            this.ImageName = imageName;
            this.CreateChildMenu = true;
            this.ShowImagesInDropDown = true;
            this.DisplayCheckBoxIfNoImage = false;
            this.menus = menus;
            this.Hint = hint;
            this.defaultPaintTool = defaultPaintTool;
        }

        public override void DoAction()
        {
            Form.ShowMenus(menus);
            Form.SetActiveMainMenuItem(this);
            if (defaultPaintTool != null)
                Form.SetMode(defaultPaintTool);
            else
                Form.SetMode(Form.DefaultMode);
            //Element.Panel.DisplayDropDownMenu(Element);
            base.DoAction();
        }
    }

    public class ToolMenu
    {
        List<ToolPanelElement> elements = new List<ToolPanelElement>();

        public List<ToolPanelElement> Elements { get { return elements; } }

        string name;

        public string Name { get { return name; } set { name = value; } }

        ToolPanel place;

        public ToolPanel Place { get { return place; } set { place = value; } }

        public void FillMenu()
        {
            place.ChildElements.Clear();
            foreach (ToolPanelElement el in elements)
            {
                if (el.Visible)
                    place.ChildElements.Add(el);
            }
            place.AssignSelfToElements();
        }

        public ToolMenu(string name, ToolPanel place)
        {
            this.name = name;
            this.place = place;
        }
    }

    public class ToolCollection: SubMenuAction
    {
        public ToolCollection(string name, string imageName, bool showImagesInDropDown, ToolMenu[] menus, string hint, PaintTool defaultPaintTool)
            : base(name, imageName, menus, hint, defaultPaintTool)
        {
            //this.Name = name;
            //this.ImageName = imageName;
            //this.CreateChildMenu = true;
            this.ShowImagesInDropDown = showImagesInDropDown;
        }

        /*public override void UpdatePicture(Action childAction)
        {
            if (Element != null && childAction.ImageIndex != -1)
            {
                ImageIndex = childAction.ImageIndex;
                Element.ImageIndex = childAction.ImageIndex;
                Element.Refresh();
            }
        }*/

        /*public override void DoAction()
        {
            //Element.Panel.DisplayDropDownMenu(Element);
            Action defaultMenuItem;
            if (Form.DefaultMenuItems.TryGetValue(this, out defaultMenuItem))
            {
                defaultMenuItem.DoAction();
            }

            base.DoAction();
        }*/
    }

    public class PaintTool: Action
    {
        public PaintTool(string hint)
        {
            this.Name = this.GetType().Name.Replace("Tool", "");
            this.ImageName = this.GetType().Name;
            this.Hint = hint;
        }

        public override void DoAction()
        {
            Form.SetMode(this);
            base.DoAction();
        }

        public virtual void SelectTool() { }
        public virtual void MouseDown(int x, int y) { }
        public virtual void MouseMove(int x, int y) { }
        public virtual void MouseUp() { }
        public virtual void Cancel() { }
        public virtual bool CanCancel() { return false; }
        public virtual void ClearStatus() { }
        public virtual bool TemporaryTool() { return false; }
    }

}
